package client

import (
	"database/sql"
	"encoding/json"
	"fmt"
	"gin-epg/internal/app/common/util"
	"gin-epg/internal/app/dao"
	"gin-epg/internal/app/entity"
	"net/url"
	"time"

	"github.com/go-resty/resty/v2"
	"github.com/spf13/cast"
)

// 所有频道url curl --location --globoff 'http://lvpepg.uni.jsa.bcs.ottcn.com:8080/cms-lvp-epg/lvps/channelList?abilityString={deviceGroupIds%22%3A[%225362%22]%2C%22districtCode%22%3A%22320900%22}&actionType=OpenNew&isShowNewProgram=true'
// 地方id列表里没有 省台不返回epg
// 易视腾江苏
var mapYstenJiangsu = map[string]string{
	"JS_CCTV1":       "CCTV1",
	"G_CETV-ZQJY-CQ": "早期教育",
	"youmankaton":    "优漫卡通",
	"G_YANCHENGTV-1": "盐城一套",
	"jsntyitao":      "南通一套",
	"jsntertao":      "南通二套",
	"jsntsantao":     "公共崇川",
	"jsczxinwen":     "常州新闻",
	"jsczdushi":      "常州都市",
	"jsczshenghuo":   "常州生活",
	"jsczgonggong":   "常州公共",
	// 更多键值对...
}

// HandleYstenJiangsuCron 处理易视腾江苏节目单
func HandleYstenJiangsuCron(beforeDay, afterDay int) error {
	dao.Logger.Infof("HandleYstenJiangsuCron start")
	source := "ystenjiangsu"

	client := resty.New()
	db := dao.SqlSession

	for dayOffset := -beforeDay; dayOffset <= afterDay; dayOffset++ {
		urlDate := time.Now().AddDate(0, 0, dayOffset).Format("20060102")
		dao.Logger.Infof("Processing date: %s", urlDate)

		for key, value := range mapYstenJiangsu {
			dao.Logger.Infof("Key: %s, Value: %s", key, value)
			// 构建URL参数
			params := url.Values{}
			params.Add("uuid", key)
			params.Add("abilityString", `{"deviceGroupIds":["5362"],"districtCode":"320900"}`)
			params.Add("startDate", urlDate)
			params.Add("endDate", urlDate)

			// 编码参数
			encodedParams := params.Encode()

			// 构建完整URL
			url := fmt.Sprintf("http://lvpepg.uni.jsa.bcs.ottcn.com:8080/cms-lvp-epg/lvps/getAllProgramlist?%s", encodedParams)

			proxyURL, err := util.GetConfigValue("proxy.proxyApiUrlYstenjiangsu")
			if err != nil {
				dao.Logger.Errorf("Error: %v", err)
			} else {
				dao.Logger.Infof("proxyApiUrlYstenjiangsu: %v", proxyURL)
				url = fmt.Sprintf("%s%s", proxyURL, url[len("http://lvpepg.uni.jsa.bcs.ottcn.com:8080"):])
			}

			resp, err := client.R().
				SetHeaders(map[string]string{
					"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36",
				}).
				Get(url)

			if err != nil {
				return fmt.Errorf("failed to get data from URL: %v", err)
			}

			var data map[string]interface{}
			if err := json.Unmarshal(resp.Body(), &data); err != nil {
				return fmt.Errorf("failed to unmarshal JSON: %v", err)
			}

			if resultCode, ok := data["resultCode"].(string); ok && resultCode == "000" {
				if content, ok := data["content"].([]interface{}); ok {
					for _, day := range content {
						dayMap := day.(map[string]interface{})
						if programs, ok := dayMap["programs"].([]interface{}); ok {
							dateParsed, _ := time.Parse("20060102", urlDate)

							// 获取当前日期范围内的已有节目记录
							var existingRecords []entity.EpgProgramCollect
							if err := db.Where(&entity.EpgProgramCollect{Channel: value, Date: entity.NullDate{sql.NullTime{Time: dateParsed, Valid: true}}, Source: source}).Find(&existingRecords).Error; err != nil {
								dao.Logger.Errorf("failed to get existing records for date %s: %v", urlDate, err)
								continue
							}

							existingMap := make(map[string]*entity.EpgProgramCollect)
							for i := range existingRecords {
								existingMap[existingRecords[i].Start] = &existingRecords[i]
							}

							var newPrograms, updatePrograms, deletePrograms []entity.EpgProgramCollect

							for _, program := range programs {
								programMap := program.(map[string]interface{})
								startTime := cast.ToInt64(programMap["startTime"])
								endTime := cast.ToInt64(programMap["endTime"])
								momentStartDate := time.Unix(startTime, 0)
								momentStopDate := time.Unix(endTime, 0)

								title := cast.ToString(programMap["programName"])
								desc := ""

								start := momentStartDate.Format("15:04")
								stop := momentStopDate.Format("15:04")

								if channel := value; channel != "" && urlDate != "" && start != "" && stop != "" {
									if existingRecord, ok := existingMap[start]; ok {
										if existingRecord.Title != title || existingRecord.End != stop {
											existingRecord.Title = title
											existingRecord.Desc = desc
											existingRecord.End = stop
											existingRecord.UpdateTime = entity.NullTime{sql.NullTime{Time: time.Now(), Valid: true}}
											updatePrograms = append(updatePrograms, *existingRecord)
										}
										delete(existingMap, start)
									} else {
										newRecord := entity.EpgProgramCollect{
											Title:      title,
											Desc:       desc,
											Source:     source,
											Channel:    channel,
											Date:       entity.NullDate{sql.NullTime{Time: dateParsed, Valid: true}},
											Start:      start,
											End:        stop,
											CreateTime: entity.NullTime{sql.NullTime{Time: time.Now(), Valid: true}},
										}
										newPrograms = append(newPrograms, newRecord)
									}
								}
							}

							// 处理需要删除的记录
							for _, record := range existingMap {
								deletePrograms = append(deletePrograms, *record)
							}

							// 执行数据库操作
							if len(updatePrograms) > 0 {
								for _, program := range updatePrograms {
									if err := db.Model(&program).Updates(entity.EpgProgramCollect{Title: program.Title, Desc: program.Desc, End: program.End, UpdateTime: program.UpdateTime}).Error; err != nil {
										dao.Logger.Errorf("update error for date %s: %v", urlDate, err)
									} else {
										dao.Logger.Debugf("update success for date %s: %v", urlDate, program)
									}
								}
							}

							if len(newPrograms) > 0 {
								for _, program := range newPrograms {
									if err := db.Create(&program).Error; err != nil {
										dao.Logger.Errorf("insert error for date %s: %v", urlDate, err)
									} else {
										dao.Logger.Debugf("insert success for date %s: %v", urlDate, program)
									}
								}
							}

							if len(deletePrograms) > 0 {
								for _, program := range deletePrograms {
									if err := db.Delete(&program).Error; err != nil {
										dao.Logger.Errorf("delete error for date %s: %v", urlDate, err)
									} else {
										dao.Logger.Debugf("delete success for date %s: %v", urlDate, program)
									}
								}
							}
						}
					}
				}
			}
		}
	}
	return nil
}
